#include "bsp_ADC.h"
#include "User_App.h"
#include "bsp_Timer.h"

// 放到APP层声明
ADC_s ADC_OBEY = {
    .a_STATE = a_DISABLE,              // 状态
    .a_ADCx = ADC1,                    // 目标ADC
    .a_DMAx = DMA1,                    // 目标DMA
    .a_DMA_Channel = LL_DMA_CHANNEL_3, // 目标DMA通道
    .a_Obj_Num = ADC_OBJ_NUM,          // ADC采集对象的数量
    .a_All_Buff = {0},                 // 所有ADC对象采集的数据
                                       // ADC对象结构体数组
    .a_Obj_Struct = {
        [0] = {
            // NTC
            .a_Obj_Buff = {0},
            .a_Obj_Value = 0,
        },
    },
};

uint8_t Adc_To_Temp(uint8_t LastTemp, uint16_t AdcValue, uint16_t ResValue);

/*  @brief  ADC数据转换处理函数
    @return 无
    @property 放到定时器中（APP层）
*/
void Ti_ADC_DATA_Function(void)
{
    bsp_Adc_Data_Assign(&ADC_OBEY);
    ADC_Test_Data_Temp = Adc_To_Temp(ADC_Test_Data_Temp, ADC_OBEY.a_Obj_Struct[0].a_Obj_Value, 10 * 1000);
}
/*  @brief  ADC触发转换函数
    @return 无
    @property 放到定时器中（APP层）
*/
void Ti_ADC_Function(void)
{
    bsp_Adc_Change(&ADC_OBEY);
}

/******************************************************************************************************************************/
const uint16_t NTC_Code[140] =
    {
        32754, 31124, 29585, 28130, 26756, 25456, 24227, 23065, 21965, 20924, // 0~9
        19938, 19004, 18119, 17281, 16486, 15732, 15016, 14338, 13693, 13082, // 10~19
        12500, 11948, 11424, 10925, 10451, 10000, 9571, 9163, 8774, 8404,     // 20~29
        8051, 7715, 7395, 7090, 6800, 6522, 6258, 6005, 5764, 5534,           // 30~39
        5315, 5105, 4905, 4713, 4530, 4355, 4188, 4028, 3875, 3728,           // 40~49
        3588, 3454, 3326, 3202, 3085, 2972, 2864, 2760, 2660, 2565,           // 50~59
        2473, 2386, 2301, 2221, 2143, 2069, 1997, 1928, 1862, 1799,           // 60~69
        1738, 1679, 1623, 1569, 1517, 1467, 1419, 1372, 1328, 1285,           // 70~79
        1243, 1203, 1165, 1128, 1092, 1058, 1025, 993, 962, 932,              // 80~89
        904, 876, 850, 824, 799, 775, 752, 730, 709, 688,                     // 90~99
        668, 648, 630, 611, 594, 577, 561, 545, 529, 515,                     // 100~109
        500, 486, 472, 460, 447, 435, 423, 412, 401, 390,                     // 110~119
        380, 370, 360, 351, 341, 333, 324, 316, 308, 300,                     // 120~129
        292, 285, 278, 271, 264, 257, 251, 245, 239, 233                      // 130~139
};

/*  @brief  转换温度
    @param  LastTemp
            上一次温度
    @param  AdcValue
            当前ADC采集值
    @param  ResValue
            阻值（单位Ω）
    @return 无
    @property 无
*/
uint8_t Adc_To_Temp(uint8_t LastTemp, uint16_t AdcValue, uint16_t ResValue)
{
    if (LastTemp > 139)
    {
        LastTemp = 25;
    }
    uint16_t NtcRes = AdcValue * ResValue / (4096 - AdcValue);
    if (NtcRes > NTC_Code[0] || NtcRes < NTC_Code[139])
    {
        return 0xFF;
    }
    else
    {
        if (NtcRes > NTC_Code[LastTemp])
        {
            LastTemp--;
        }
        if (NtcRes < NTC_Code[LastTemp])
        {
            LastTemp++;
        }
    }
    return LastTemp;
}
/******************************************************************************************************************************/
/*  @brief  初始化ADC采集
    @return 无
    @property 放到程序初始化位置
*/
void bsp_Adc_Init(ADC_s *obj)
{
    // 配置DMA（ADC）
    LL_DMA_SetPeriphAddress(obj->a_DMAx, obj->a_DMA_Channel, LL_ADC_DMA_GetRegAddr(obj->a_ADCx, LL_ADC_DMA_REG_REGULAR_DATA)); // 设置DMA的外设地址，并绑定ADC的数据转换地址
    LL_DMA_SetMemoryAddress(obj->a_DMAx, obj->a_DMA_Channel, (uint32_t)&obj->a_All_Buff);                                      // DMA获取数据后存放的位置
    LL_DMA_SetDataLength(obj->a_DMAx, obj->a_DMA_Channel, obj->a_Obj_Num * ADC_OBJ_DATA_NUM);                                  // 设置DMA数据长度

    // 配置ADC
    LL_ADC_REG_SetDMATransfer(obj->a_ADCx, LL_ADC_REG_DMA_TRANSFER_NONE); // 设置ADC组定期转换数据传输，默认不通过DMA
    LL_ADC_StartCalibration(obj->a_ADCx);                                 // 校准ADC
    while (LL_ADC_IsCalibrationOnGoing(obj->a_ADCx))                      // 等待校准完成
        ;
    LL_ADC_Enable(obj->a_ADCx);                                                // 软件启动ADC
    LL_ADC_REG_SetDMATransfer(obj->a_ADCx, LL_ADC_REG_DMA_TRANSFER_UNLIMITED); // 设置ADC组定期转换数据传输，DMA+无限模式
    LL_DMA_EnableChannel(obj->a_DMAx, obj->a_DMA_Channel);                     // 使能DMA的通道
    LL_ADC_REG_StartConversion(obj->a_ADCx);                                   // 启动ADC组常规转换
}
/*  @brief  ADC数据分配
    @param  *obj
            ADC对象
    @return 无
    @property 需要定时去分配
*/
void bsp_Adc_Data_Assign(ADC_s *obj)
{
    uint8_t number_A = 0;
    uint8_t number_B = 0;
    uint32_t Value_A = 0;
    // 分配数据
    for (uint16_t number_C = 0; number_C < ADC_OBJ_NUM * ADC_OBJ_DATA_NUM; number_C++)
    {
        number_A %= obj->a_Obj_Num;
        obj->a_Obj_Struct[number_A].a_Obj_Buff[number_B] = obj->a_All_Buff[number_C];

        if (number_A == (obj->a_Obj_Num - 1))
        {
            number_B++;
        }
        number_A++;
    }
    // 累加算平均值
    for (uint8_t number_D = 0; number_D < ADC_OBJ_NUM; number_D++)
    {
        for (uint8_t number_E = 0; number_E < ADC_OBJ_DATA_NUM; number_E++)
        {
            Value_A += obj->a_Obj_Struct[number_D].a_Obj_Buff[number_E];
        }
        obj->a_Obj_Struct[number_D].a_Obj_Value = Value_A / ADC_OBJ_DATA_NUM; // 求平均值
        Value_A = 0;
    }
}
/*  @brief  ADC触发转换（软件触发方式）
    @return 无
    @property 放在定时器中
*/
void bsp_Adc_Change(ADC_s *obj)
{
    LL_ADC_REG_StartConversion(obj->a_ADCx); // 软件启动ADC转换
    while (!LL_ADC_IsActiveFlag_EOS(obj->a_ADCx))
    {
        // 等待转换结束
    }
    LL_ADC_ClearFlag_EOS(obj->a_ADCx); // 清除转换结束标志位
}

// bsp_TIM_t Ti_ADC;
// bsp_TIM_t Ti_ADC_DATA;
/*  @brief  ADC采集调试程序
    @return 无
    @property 无
*/
void bsp_Adc_Debug(void)
{
    bsp_Adc_Init(&ADC_OBEY);

//    Ti_obj_New(&Ti_ADC, 20, Ti_RUN, Ti_ADC_Function);
//    Ti_obj_New(&Ti_ADC_DATA, 20 * ADC_OBJ_DATA_NUM, Ti_RUN, Ti_ADC_DATA_Function);

    while (1)
    {
        bsp_Ti_All_Handle();
    }
}
/******************************************************************************************************************************/
